扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
为何需要任务调度?
在web应用中,大多数任务是以一种"防止用户长时间等待"的方式完成的。在Google搜索这样的例子中,减少等待时间对用户体验来说至关重要。异步任务的一种解决方案是在用户提交后生成一个线程(来处理异步任务),但这也不能解决那些需要以一定时间间隔重复运行任务、或在每天的指定时间运行任务的情况。
让我们从一个数据库报表的例子来看看任务调度能如何帮助改善系统设计。报表可能是错综复杂的,这取决于用户所需数据的种类,以及是否需要从一个或多个数据库收集大量数据。用户可能需要很长时间来运行这样的"按需"报表。因此,我们向这个报表示例中添加任务调度机制,以便用户可以安排在任何他们需要的时间生成报表,并以PDF或其他格式在email中发送。用户可以让报表在每天的凌晨2:22,系统正处于低负荷时运行;也可以选择只在特定时间运行一次。通过在报表应用中加入任务调度,我们可以为产品添加一项有用的功能,并改善用户体验。
幸运的是,有一个强大的开源解决方案可以让我们以标准的方式在web应用(或任何Java应用)中实施任务调度。以下示例展示了在web应用中,如何使用Quartz来创建一个任务调度框架。这个示例还使用了Struts Action framework 插件,以便在web应用启动时初始化任务调度机制。Struts是最常见的MVC框架,为大多数开发人员所熟悉。当然除此之外还有许多框架可以协助在web应用中实现MVC模式。
启动时初始化任务调度器
我们首先要做的是建立一个Struts插件,让它在容器启动时创建我们的任务调度器。在以下例子中,我们选择Tomcat作为web应用容器,不过这些示例在其他容器中也应当可以运行。我们要创建一个Struts插件类,并在struts-config.xml中加入几行代码以使之可以工作。
这个插件有两个可配置的初始化参数:startOnLoad指定是否要在容器启动时立即启动任务调度器,而 startupDelay指定启动任务调度器之前的等待时间。启动延时很有用,因为我们可能需要首先执行一些更重要的初始化步骤。此外还可以使用listener机制,以更复杂的方式来通知SchedulerPlugIn何时启动Quartz Scheduler。
<plug-in className="SchedulerPlugIn"> <set-property property="startOnLoad" value="false" /> <set-property property="startupDelay" value="0" /> </plug-in> |
我们要创建的是一个实现Struts插件接口org.apache.struts.action.PlugIn的单子类SchedulerPlugIn。Struts会按照配置文件中出现的顺序初始化各个插件。要特别注意的是init()方法中的代码,在此我们初始化了所需的Quartz对象,并得到Scheduler。我们的任务信息就要提交到此org.quartz.Scheduler对象,后者将在随后讨论。Scheduler对象由Quartz servlet根据其配置初始化,就像Struts初始化它的ActionServlet类一样。让我们来看init()方法:
public void init(ActionServlet actionServlet, System.out.println("Initializing Scheduler PlugIn for Jobs!"); // Retrieve the factory from the ServletContext. // Start the scheduler in case, it isn't started yet |
濠电姷鏁告慨鐑姐€傛禒瀣劦妞ゆ巻鍋撻柛鐔锋健閸┾偓妞ゆ巻鍋撶紓宥咃躬楠炲啫螣鐠囪尙绐為梺褰掑亰閸撴盯鎮惧ú顏呪拺闂傚牊鍗曢崼銉ョ柧婵犲﹤瀚崣蹇旂節婵犲倻澧涢柛瀣ㄥ妽閵囧嫰寮介妸褋鈧帡鏌熼挊澶婃殻闁哄瞼鍠栭幃婊堝煛閸屾稓褰嬮柣搴ゎ潐濞叉ê鐣濈粙璺ㄦ殾闁割偅娲栭悡娑㈡煕鐏炲墽鐭嬫繛鍫熸倐濮婄粯鎷呯粵瀣異闂佹悶鍔嬮崡鍐茬暦閵忋倕鍐€妞ゆ劑鍎卞皬闂備焦瀵х粙鎴犫偓姘煎弮瀹曚即宕卞Ο闀愮盎闂侀潧鐗嗛幊搴㈡叏椤掆偓閳规垿鍩ラ崱妞剧凹濠电姰鍨洪敋閾荤偞淇婇妶鍛櫤闁稿鍊圭换娑㈠幢濡纰嶉柣搴㈣壘椤︾敻寮诲鍫闂佸憡鎸鹃崰搴敋閿濆鏁嗗〒姘功閻绻涢幘鏉戠劰闁稿鎹囬弻锝呪槈濞嗘劕纾抽梺鍝勬湰缁嬫垿鍩為幋锕€宸濇い鏇炴噺閳诲﹦绱撻崒娆戝妽妞ゃ劌鎳橀幆宀勫磼閻愰潧绁﹂柟鍏肩暘閸斿矂鎮為崹顐犱簻闁圭儤鍨甸鈺呮倵濮橆剦妲归柕鍥у瀵粙濡歌閸c儳绱撴担绛嬪殭婵☆偅绻堝濠氭偄绾拌鲸鏅i悷婊冪Ч閹﹢鎳犻鍌滐紲闁哄鐗勯崝搴g不閻愮儤鐓涢悘鐐跺Г閸犳﹢鏌℃担鐟板鐎规洜鍠栭、姗€鎮╅搹顐ら拻闂傚倷娴囧畷鍨叏閹惰姤鈷旂€广儱顦崹鍌炴煢濡尨绱氶柨婵嗩槸缁€瀣亜閺嶃劎鈽夋繛鍫熺矒濮婅櫣娑甸崨顔俱€愬銈庡亝濞茬喖宕洪埀顒併亜閹哄棗浜鹃梺鎸庢穿婵″洤危閹版澘绫嶉柛顐g箘椤撴椽姊虹紒妯哄鐎殿噮鍓欒灃闁告侗鍠氶崢鎼佹⒑閸撴彃浜介柛瀣閹﹢鏁冮崒娑氬幈闁诲函缍嗛崑鍡樻櫠椤掑倻纾奸柛灞剧☉缁椦囨煙閻熸澘顏柟鐓庢贡閹叉挳宕熼棃娑欐珡闂傚倸鍊风粈渚€骞栭銈傚亾濮樺崬鍘寸€规洖缍婇弻鍡楊吋閸涱垽绱遍柣搴$畭閸庨亶藝娴兼潙纾跨€广儱顦伴悡鏇㈡煛閸ャ儱濡煎褜鍨伴湁闁绘ǹ绉鍫熺畳闂備焦瀵х换鍌毼涘Δ鍛厺闁哄洢鍨洪悡鍐喐濠婂牆绀堟慨妯挎硾閽冪喖鏌曟繛褍瀚烽崑銊╂⒑缂佹ê濮囨い鏇ㄥ弮閸┿垽寮撮姀鈥斥偓鐢告煥濠靛棗鈧懓鈻嶉崶銊d簻闊洦绋愰幉楣冩煛鐏炵偓绀嬬€规洟浜堕、姗€鎮㈡總澶夌处